package com.yhm.mybatis.intercepts;


import com.yhm.mybatis.Common;
import com.yhm.mybatis.bean.YhmAbstractRoutingDataSource;
import com.yhm.mybatis.utils.SpringContextUtil;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Properties;


@Intercepts({
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})

})
public class YhmRWDBIntercept implements Interceptor{

  private YhmAbstractRoutingDataSource yhmAbstractRoutingDataSource;
  @Override
  public Object intercept(Invocation invocation) throws Throwable {


    Object[] args  = invocation.getArgs();
    MappedStatement ms = (MappedStatement) args[0];
    yhmAbstractRoutingDataSource = SpringContextUtil.getBean(YhmAbstractRoutingDataSource.class);



    if (ms.getSqlCommandType().equals(SqlCommandType.SELECT)) {
      Common.threadLocalDbRoutingInfoStr.set("read");
    } else if (ms.getSqlCommandType().equals(SqlCommandType.DELETE)) {
      Common.threadLocalDbRoutingInfoStr.set("write");
    }else if (ms.getSqlCommandType().equals(SqlCommandType.UPDATE)) {
      Common.threadLocalDbRoutingInfoStr.set("write");
    }else if (ms.getSqlCommandType().equals(SqlCommandType.INSERT)) {
      Common.threadLocalDbRoutingInfoStr.set("write");
    }
    if (Common.threadLocalDbRoutingInfoStr.get().equals("write")) {
      yhmAbstractRoutingDataSource.setDefaultTargetDataSource(yhmAbstractRoutingDataSource.getWriteDataSource());

    }else {
      yhmAbstractRoutingDataSource.setDefaultTargetDataSource(yhmAbstractRoutingDataSource.getReadDataSource());

    }

    return invocation.proceed();
  }

  @Override
  public Object plugin(Object target) {
    if (target instanceof Executor) {
      return Plugin.wrap(target, this);
    } else {
      return target;
    }
  }

  @Override
  public void setProperties(Properties properties) {

  }
}
